/**
 * @file dev_valve.c
 * @brief 电磁阀设备
 * 
 * @author dalin (dalin@open-robot.com)
 * @version 1.0
 * @date 2023-05-10
 * 
 * @copyright Copyright (c) 2023  Open Robot Tech.co, Ltd
 * 
 * @par 修改日志:
 * <table>
 * <tr><th>Date       <th>Version <th>Author  <th>Description
 * <tr><td>2023-05-10 <td>1.0     <td>dalin     <td>initial
 * <tr><td>2023-05-17 <td>1.1     <td>dalin     <td>添加维持和周期模式
 * </table>
 */

#include "drv_gpio.h"
#include "dev_valve.h"
#include "mlog.h"



/* 电磁阀对应的硬件配置 */
devValveConfig_t valve_list[VALVE_MAX] =
{
    {"valve0", {DRV_GPIOC, DRV_PIN_13, 0}},
    {"valve1", {DRV_GPIOB, DRV_PIN_5 , 0}},
    {"valve2", {DRV_GPIOB, DRV_PIN_4 , 0}},
    {"valve3", {DRV_GPIOC, DRV_PIN_11, 0}},
    {"valve4", {DRV_GPIOC, DRV_PIN_2 , 0}},
    {"valve5", {DRV_GPIOC, DRV_PIN_15, 0}},
    {"valve6", {DRV_GPIOC, DRV_PIN_14, 0}},
    {"valve7", {DRV_GPIOC, DRV_PIN_3 , 0}},
};

devValve_t dev_valve;


/************************************ api ************************************/

/**
 * @brief 初始化电磁阀设备
 * 
 * @note  默认使能
 */
void dev_valve_init(void)
{
    dev_valve.valve_enabled = true;

    for(int i = 0; i < VALVE_MAX; i++)
    {
        dev_valve.dev[i].enable   = true;
        dev_valve.dev[i].mode     = VALVE_NORMAL;
        dev_valve.dev[i].state    = LOW;
        drv_gpio_write(valve_list[i].gpio, dev_valve.dev[i].state);
    }
}

/**
 * @brief 卸载电磁阀设备
 * 
 * 
 */
void dev_valve_deinit(void)
{
    dev_valve.valve_enabled = false;

    for(int i = 0; i < VALVE_MAX; i++)
    {
        dev_valve.dev[i].enable   = false;
        dev_valve.dev[i].mode     = VALVE_ONINIT;
        dev_valve.dev[i].state    = LOW;
        drv_gpio_write(valve_list[i].gpio, dev_valve.dev[i].state);
    }
}

/**
 * @brief 电磁阀使能
 * 
 * 
 * @return * void 
 */
void dev_valve_enable(void)
{
    dev_valve.valve_enabled = true;
}

/**
 * @brief 电磁阀失能
 * 
 * 
 * @return * void 
 */
void dev_valve_disable(void)
{
    dev_valve.valve_enabled = false;
}

/**
 * @brief 设置设备状态
 * 
 * @param  valve            : 电磁阀ID
 * @param  state            : 电磁阀要设置的状态
 * 
 */
void dev_valve_state_control(valveId_e valve, bool state)
{
    drv_gpio_write(valve_list[valve].gpio, state);
}

/**
 * @brief 获取设备状态
 * 
 * @param  valve            : 设备ID
 * 
 * @return true     ：打开状态
 * @return false    ：关闭状态
 */
bool dev_valve_state_read(valveId_e id)
{
    return dev_valve.dev[id].state;
}

/**
 * @brief 设置设备模式
 * 
 * @param  id               : 电磁阀ID
 * @param  mode             : 电磁阀模式
 * 
 */
void dev_valve_set_mode(valveId_e id, valveMode_e mode)
{
    dev_valve.dev[id].mode = mode;
}

/************************************ timer ************************************/

/**
 * @brief 定时器回调中具体做的事
 * 
 * @param  valve_id         : xxx
 * 
 */
static void dev_valve_callback_process(valveId_e valve_id)
{
    /* 维持模式只进行一次就切换成正常模式，并并删除掉定时器 */
    if(dev_valve.dev[valve_id].mode == VALVE_HOLD)
    {
        dev_valve.dev[valve_id].state  = !dev_valve.dev[valve_id].state;
        dev_valve_state_control(valve_id, dev_valve.dev[valve_id].state);

        dev_valve.dev[valve_id].mode = VALVE_NORMAL;
        dev_valve.dev[valve_id].time = 0;
        osTimerDelete(dev_valve.dev[valve_id].timer_id);

        log_info("dev_valve%d delete timer", valve_id);
        // log_info("dev_valve once test:%d", valve_id)
    }
    /* 周期模式需要进行剩余循环次数检测 */
    else if(dev_valve.dev[valve_id].mode == VALVE_PERI)
    {

        if(dev_valve.dev[valve_id].num == 0)
        {
            log_info("dev_valve%d delete timer", valve_id);
            dev_valve.dev[valve_id].mode = VALVE_NORMAL;
            dev_valve.dev[valve_id].time = 0;
            osTimerDelete(dev_valve.dev[valve_id].timer_id);
        }
        else
        {
            dev_valve.dev[valve_id].state  = !dev_valve.dev[valve_id].state;
            dev_valve_state_control(valve_id, dev_valve.dev[valve_id].state);

            log_info("dev_valve peri test -> num: %d", dev_valve.dev[valve_id].num);
        }
        dev_valve.dev[valve_id].num--;
    }
    else
    {
        log_error("valve callback mode error: %d", valve_id);
    }
}


/* 更具设备的数量进行添加 */
void timer_callback0(void * argument)
{
    uint8_t valve_id = VALVE_0;
    dev_valve_callback_process(valve_id);
}
void timer_callback1(void * argument)
{
    uint8_t valve_id = VALVE_1;
    dev_valve_callback_process(valve_id);
}
void timer_callback2(void * argument)
{
    uint8_t valve_id = VALVE_2;
    dev_valve_callback_process(valve_id);
}
void timer_callback3(void * argument)
{
    uint8_t valve_id = VALVE_3;
    dev_valve_callback_process(valve_id);
}
void timer_callback4(void * argument)
{
    uint8_t valve_id = VALVE_4;
    dev_valve_callback_process(valve_id);
}
void timer_callback5(void * argument)
{
    uint8_t valve_id = VALVE_5;
    dev_valve_callback_process(valve_id);
}
void timer_callback6(void * argument)
{
    uint8_t valve_id = VALVE_6;
    dev_valve_callback_process(valve_id);
}
void timer_callback7(void * argument)
{
    uint8_t valve_id = VALVE_7;
    dev_valve_callback_process(valve_id);
}


/**
 * @brief 为指定设备创建软件定时器
 * 
 * @param  id               : 设备ID
 * @param  mode             : 运行的模式：限制为：维持模式或者周期模式
 * @param  time             : 定时器时间
 * 
 */
void dev_valve_timer_create(valveId_e id, uint8_t mode, uint16_t time, uint8_t num)
{
    uint8_t time_mode = 0;
    uint8_t err_flag = 0;
    if(mode == VALVE_HOLD)
        time_mode = ONCE_TIME;
    else if(mode == VALVE_PERI)
    {
        time_mode = PERI_TIME;
        dev_valve.dev[id].num = num;
    }  
    else 
        err_flag = 1;

    if(err_flag == 0)
    {
        switch (id)
        {
        case VALVE_0:
                dev_valve.dev[id].mode = mode;
                osTimerDef(valveTimer0, timer_callback0);
                dev_valve.dev[id].timer_id = osTimerCreate(osTimer(valveTimer0), time_mode, NULL);
            break;
        case VALVE_1:
                dev_valve.dev[id].mode = mode;
                osTimerDef(valveTimer1, timer_callback1);
                dev_valve.dev[id].timer_id = osTimerCreate(osTimer(valveTimer1), time_mode, NULL);
            break;
        case VALVE_2:
                dev_valve.dev[id].mode = mode;
                osTimerDef(valveTimer2, timer_callback2);
                dev_valve.dev[id].timer_id = osTimerCreate(osTimer(valveTimer2), time_mode, NULL);
            break;
        case VALVE_3:
                dev_valve.dev[id].mode = mode;
                osTimerDef(valveTimer3, timer_callback3);
                dev_valve.dev[id].timer_id = osTimerCreate(osTimer(valveTimer3), time_mode, NULL);
            break;
        case VALVE_4:
                dev_valve.dev[id].mode = mode;
                osTimerDef(valveTimer4, timer_callback4);
                dev_valve.dev[id].timer_id = osTimerCreate(osTimer(valveTimer4), time_mode, NULL);
            break;
        case VALVE_5:
                dev_valve.dev[id].mode = mode;
                osTimerDef(valveTimer5, timer_callback5);
                dev_valve.dev[id].timer_id = osTimerCreate(osTimer(valveTimer5), time_mode, NULL);
            break;
        case VALVE_6:
                dev_valve.dev[id].mode = mode;
                osTimerDef(valveTimer6, timer_callback6);
                dev_valve.dev[id].timer_id = osTimerCreate(osTimer(valveTimer6), time_mode, NULL);
            break;
        case VALVE_7:
                dev_valve.dev[id].mode = mode;
                osTimerDef(valveTimer7, timer_callback7);
                dev_valve.dev[id].timer_id = osTimerCreate(osTimer(valveTimer7), time_mode, NULL);
            break;
        
        default:
            break;
        }
        osTimerStart(dev_valve.dev[id].timer_id,time);
    }
    else
    {
        log_error("create timer failed");
    }
}

/**
 * @brief 卸载定时器
 * 
 * @param  valve_id         : 设备ID
 * 
 */
void dev_valve_timer_destroy(valveId_e valve_id)
{
    osTimerDelete(dev_valve.dev[valve_id].timer_id);
}


/************************************ test ************************************/
void dev_valve_test(void)
{
    // static int dev_valve = 0;
    // if(dev_valve >= 100)
    // {
    //     dev_valve = 0;
    //     for(int i = 0; i < VALVE_MAX; i++)
    //         drv_gpio_toggle(valve_list[i].gpiox, valve_list[i].pinx);
    // }
    // dev_valve++;

    dev_valve_init();
    dev_valve_timer_create(VALVE_0, VALVE_HOLD, 1000, 0);
    dev_valve_timer_create(VALVE_1, VALVE_PERI, 1000, 100);

}

